# -*- coding: utf-8 -*-
# @Time    : 2019/10/17 16:46
# @Author  : ZSQ
# @Email   : zsq199170918@163.com
# @FileName: changzhou.py
# @Software: PyCharm
import scrapy

import re
import json
import base64
import logging
from copy import copy, deepcopy
from FDC_spider.constants import CZ_SALE_STATE_LI
from FDC_spider.items import FdcEstateGuidItem, FdcBuildingItem, FdcRoomItem

logger = logging.getLogger(__name__)


class ChangzhouSpider(scrapy.Spider):
    name = 'changzhou'
    allowed_domains = ['gs.czfdc.com.cn']
    start_urls = ['http://gs.czfdc.com.cn/newxgs/Pages/Code/Xjfas.ashx']

    def start_requests(self):
        # 构造POST请求参数
        data = dict(
            method='GetYszData',
            ysxkz='',
            kfs='',
            lpmc='',
            page='1',
        )
        yield scrapy.FormRequest(
            ChangzhouSpider.start_urls[0],
            formdata=data,
            meta=dict(page_num=1),
        )

    def parse(self, response):
        current_page = response.meta['page_num']
        resp = json.loads(response.body.decode('gb2312', errors='ignore'))
        resp_dict = json.loads(resp) if isinstance(resp, str) else resp
        # 获取当前页许可证列表
        permit_dict_li = resp_dict.get('Rows', [])
        if len(permit_dict_li):
            for permit_dict in permit_dict_li:
                item_eg = FdcEstateGuidItem()
                item_eg['districtName'] = permit_dict.get('SANJAK', None)
                item_eg['projectName'] = permit_dict.get('PRJNAME', None)
                item_eg['preSalePermit'] = permit_dict.get('PRENUM', None)
                item_eg['developerName'] = permit_dict.get('NAME', None)
                item_eg['certDate'] = permit_dict.get('PresaleCertificateDate', None)
                item_eg['estateAddress'] = permit_dict.get('BSIT', None)
                item_eg['CA'] = permit_dict.get('PIZHUN', None)
                item_eg['CA'] = item_eg['CA'].strip() if item_eg['CA'] else item_eg['CA']
                item_eg['preSaleBuilding'] = permit_dict.get('CONSNUM', None)
                item_eg['approvalRoomNo'] = permit_dict.get('YSROOMNUMS', None)
                item_eg['approvalArea'] = permit_dict.get('YSROOMBAREA', None)
                item_eg['permitId'] = permit_dict.get('psaleid', None)
                jgyh = permit_dict.get('jgyh', None)
                jgyh = jgyh.strip() if jgyh and jgyh.strip() else None
                jgzh = permit_dict.get('jgzh', None)
                jgzh = jgzh.strip() if jgzh and jgzh.strip() else None
                if (jgyh and self.parse_digit(jgyh)) or (jgzh and not self.parse_digit(jgzh)):
                    item_eg['preSaleDepositBank'] = jgzh
                    item_eg['preSaleAccountNum'] = jgyh
                else:
                    item_eg['preSaleDepositBank'] = jgyh
                    item_eg['preSaleAccountNum'] = jgzh
                yield item_eg

                """获取楼栋列表"""
                # 构造POST请求参数
                data = dict(
                    method='GetLpLzList',
                    id=item_eg['permitId'],
                )
                yield scrapy.FormRequest(
                    ChangzhouSpider.start_urls[0],
                    formdata=data,
                    callback=self.parse_building_li,
                    meta=dict(item_eg=deepcopy(item_eg)),
                )
        else:
            logger.warning('第{}页 许可证列表获取为空'.format(current_page))

        # 翻页
        print('>>>>>>>>第{}页<<<<<<<<'.format(current_page))
        try:
            permit_total_num = resp_dict.get('Total', None)
            total_page = int(permit_total_num) // 10 if int(permit_total_num) % 10 == 0 else int(
                permit_total_num) // 10 + 1
            for page_num in range(2, total_page + 1):
                # 构造POST翻页参数
                data = dict(
                    method='GetYszData',
                    ysxkz='',
                    kfs='',
                    lpmc='',
                    page=str(page_num),
                )
                yield scrapy.FormRequest(
                    ChangzhouSpider.start_urls[0],
                    formdata=data,
                    meta=dict(page_num=page_num),
                )
        except Exception as e:
            logger.error('第{}页 许可证列表页翻页请求失败  error_msg:{}'.format(current_page, e))

    def parse_building_li(self, response):
        """
        获取楼栋列表
        :param response:
        :return:
        """
        item_eg = copy(response.meta['item_eg'])
        resp = json.loads(response.body.decode('gb2312', errors='ignore'))
        resp_li = json.loads(resp) if isinstance(resp, str) else resp
        if len(resp_li):
            for bd_dict in resp_li:
                item_bd = FdcBuildingItem()
                item_bd['districtName'] = item_eg['districtName']
                item_bd['projectName'] = item_eg['projectName']
                item_bd['preSalePermit'] = item_eg['preSalePermit']
                item_bd['developerName'] = item_eg['developerName']
                item_bd['permitId'] = bd_dict.get('psaleid', None)
                item_bd['blockName'] = bd_dict.get('housenum', None)
                item_bd['buildingId'] = bd_dict.get('houseid', None)

                """获取楼栋详情"""
                # 构造POST请求参数
                bd_data = dict(
                    method='GetTsBySalestate',
                    houseID=item_bd['buildingId'],
                    psaleID=item_bd['permitId'],
                )
                yield scrapy.FormRequest(
                    ChangzhouSpider.start_urls[0],
                    formdata=bd_data,
                    callback=self.parse_building,
                    meta=dict(item_bd=deepcopy(item_bd)),
                )

                """获取房号列表"""
                # 构造POST请求参数
                rm_li_data = dict(
                    method='GetShowData',
                    houseID=item_bd['buildingId'],
                    saleSate='',
                    cell='',
                    psaleID=item_bd['permitId'],
                )
                yield scrapy.FormRequest(
                    ChangzhouSpider.start_urls[0],
                    formdata=rm_li_data,
                    callback=self.parse_room_li,
                    meta=dict(item_bd=deepcopy(item_bd)),
                )
        else:
            logger.warning(
                '{}-{}-{}-{} 楼栋列表获取为空'.format(item_eg['districtName'], item_eg['projectName'], item_eg['preSalePermit'],
                                              item_eg['developerName']))

    def parse_building(self, response):
        """
        获取楼栋详情
        :param response:
        :return:
        """
        item_bd = copy(response.meta['item_bd'])
        resp = json.loads(response.body.decode('gb2312', errors='ignore'))
        resp_li = json.loads(resp) if isinstance(resp, str) else resp
        saleableRoomNo = 0
        totalRoomNo = 0
        if len(resp_li):
            for state_dict in resp_li:
                try:
                    state_index = int(state_dict.get('salestate', 2))
                    state = CZ_SALE_STATE_LI[state_index]
                    rm_num = int(state_dict.get('allnum', 0))
                except Exception as e:
                    logger.error(
                        '{}-{}-{}-{} 楼栋详情获取出错  error_msg:{}'.format(item_bd['districtName'], item_bd['projectName'],
                                                                    item_bd['preSalePermit'], item_bd['blockName'], e))
                else:
                    if state == '未备案':
                        saleableRoomNo += rm_num
                    totalRoomNo += rm_num
        else:
            logger.warning(
                '{}-{}-{}-{} 楼栋详情获取为空'.format(item_bd['districtName'], item_bd['projectName'], item_bd['preSalePermit'],
                                              item_bd['blockName']))
        item_bd['saleableRoomNo'] = saleableRoomNo
        item_bd['totalRoomNo'] = totalRoomNo
        yield item_bd

    def parse_room_li(self, response):
        """
        获取房号列表
        :param response:
        :return:
        """
        item_bd = copy(response.meta['item_bd'])
        resp_str = response.body.decode()
        resp_li = self._parse_content(resp_str)
        if len(resp_li):
            for rm_dict in resp_li:
                item_rm = FdcRoomItem()
                item_rm['districtName'] = item_bd['districtName']
                item_rm['projectName'] = item_bd['projectName']
                item_rm['preSalePermit'] = item_bd['preSalePermit']
                item_rm['blockName'] = item_bd['blockName']
                item_rm['buildingId'] = item_bd['buildingId']
                if isinstance(rm_dict, dict):
                    item_rm['unitName'] = rm_dict.get('curcell', None) if rm_dict.get('curcell', None) != '无' else None
                    item_rm['roomNo'] = rm_dict.get('roomlabel', None)
                    item_rm['roomUse'] = rm_dict.get('buse', None)
                    item_rm['saleStatus'] = rm_dict.get('svl', None) if rm_dict.get('svl', None) and rm_dict.get('svl',
                                                                                                                 None) != '未备案' else '可售'
                    item_rm['roomArea'] = rm_dict.get('BuildingArea', None)
                    item_rm['roomId'] = rm_dict.get('roomid', None)
                    item_rm['roomTotalPrice'] = rm_dict.get('ContractPrice', None)
                    item_rm['roomTotalPrice'] = item_rm['roomTotalPrice'] if item_rm['roomTotalPrice'] else None
                    yield item_rm
        else:
            logger.warning(
                '{}-{}-{}-{} 房号列表获取为空'.format(item_bd['districtName'], item_bd['projectName'], item_bd['preSalePermit'],
                                              item_bd['blockName']))

    @staticmethod
    def parse_digit(cont_):
        """
        判断是否包含数字
        :param cont_:
        :return:
        """
        if cont_:
            regex = re.compile(r'[0-9]+')
            ret_li = regex.findall(cont_)
            if len(ret_li):
                return True
        return False

    def _parse_content(self, cont_):
        """
        反解析加密信息
        :return:
        """
        cont_str = base64.b64decode(cont_).decode('utf-8', errors='ignore')
        cont_str = re.sub(r".*?:", '', cont_str, count=1)
        cont_str = '[{"ipage":' + cont_str
        cont_li = json.loads(cont_str)
        return cont_li
